package com.dhcc.core.config;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.servlet.MultipartConfigElement;

import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextListener;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.dhcc.core.config.properties.SysProperties;
import com.dhcc.core.framework.referer.RefererFilter;
import com.dhcc.core.framework.xss.XssFilter;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;

/**
 * web 配置类
 *
 * @ClassName: WebConfig
 * @Description: 描述
 * @author: cyf
 * @date: 2018年1月2日 上午9:42:53
 */
@Configuration
public class WebConfig {

	@Autowired
    SysProperties sysProperties;
    /**
     * druidServlet注册
     */
    @Bean
    public ServletRegistrationBean<StatViewServlet> druidServletRegistration() {
        ServletRegistrationBean<StatViewServlet> registration = new ServletRegistrationBean<StatViewServlet>(new StatViewServlet());
        registration.addUrlMappings("/druid/*");
        return registration;
    }

    /**
     * druid监控 配置URI拦截策略
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean<WebStatFilter> druidStatFilter() {
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<WebStatFilter>(new WebStatFilter());
        // 添加过滤规则.
        filterRegistrationBean.addUrlPatterns("/*");
        // 添加不需要忽略的格式信息.
        filterRegistrationBean.addInitParameter("exclusions",
                "/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid,/druid/*");
        // 开启session统计功能
        filterRegistrationBean.addInitParameter("sessionStatEnable", "true");
        // 用于session监控页面的用户名显示 需要登录后主动将username注入到session里
        filterRegistrationBean.addInitParameter("principalSessionName", "username");
        return filterRegistrationBean;
    }

    /**
     * druid数据库连接池监控
     */
    @Bean
    public DruidStatInterceptor druidStatInterceptor() {
        return new DruidStatInterceptor();
    }

    @Bean
    public JdkRegexpMethodPointcut druidStatPointcut() {
        JdkRegexpMethodPointcut druidStatPointcut = new JdkRegexpMethodPointcut();
        String patterns = "com.dhcc.*.service.*";
        // 可以set多个
        druidStatPointcut.setPatterns(patterns);
        return druidStatPointcut;
    }

    /**
     * druid数据库连接池监控
     */
    @Bean
    public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator() {
        BeanTypeAutoProxyCreator beanTypeAutoProxyCreator = new BeanTypeAutoProxyCreator();
        beanTypeAutoProxyCreator.setTargetBeanType(DruidDataSource.class);
        beanTypeAutoProxyCreator.setInterceptorNames("druidStatInterceptor");
        return beanTypeAutoProxyCreator;
   }

    /**
     * druid 为druidStatPointcut添加拦截
     *
     * @return
     */
    @Bean
    public Advisor druidStatAdvisor() {
        return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor());
    }

    /**
     * XssFilter注册
     */
    @Bean
    public FilterRegistrationBean<XssFilter> xssFilterRegistration() {
        XssFilter xssFilter = new XssFilter();
        List<String> urlExclusion = Arrays.asList(sysProperties.getXssAllowedUrl());
        xssFilter.setUrlExclusion(urlExclusion);
        FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<XssFilter>(xssFilter);
        registration.addUrlPatterns("/*");
        registration.setOrder(2);
        return registration;
    }

    /**
     * RefererFilter注册
     */
    @Bean
    public FilterRegistrationBean<RefererFilter> referarFilterRegistration() {
        RefererFilter referarFilter = new RefererFilter();
        List<String> hostExclusion = Arrays.asList(sysProperties.getRefererAllowedHost());
        referarFilter.setHostExclusion(hostExclusion);
        FilterRegistrationBean<RefererFilter> registration = new FilterRegistrationBean<RefererFilter>(referarFilter);
        registration.addUrlPatterns("/*");
        registration.setOrder(1);
        return registration;
    }

    /**
     * RequestContextListener注册
     */
    @Bean
    public ServletListenerRegistrationBean<RequestContextListener> requestContextListenerRegistration() {
        return new ServletListenerRegistrationBean<>(new RequestContextListener());
    }

    /**
     * 附件上传大小设置
     */
    @Bean
    public MultipartConfigElement multipartConfigElement(SysProperties sysProperties) {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxFileSize(sysProperties.getFileUploadMaxSize());
        return factory.createMultipartConfig();
    }

    /**
     * 验证码生成相关
     */
    @Bean
    public DefaultKaptcha kaptcha() {
        Properties properties = new Properties();
        // 是否有边框  
        properties.put("kaptcha.border", "no");
        // 边框颜色  
        properties.put("kaptcha.border.color", "105,179,90");
        // 验证码宽度  
        properties.put("kaptcha.image.width", "100");
        // 验证码高度  
        properties.put("kaptcha.image.height", "40");
        // 生成验证码内容范围  
        properties.put("kaptcha.textproducer.char.string", "0123456789");
        // 验证码个数  
        properties.put("kaptcha.textproducer.char.length", "4");
        // 边框厚度  
        properties.put("kaptcha.border.thickness", "1");
        // 验证码字体颜色  
        properties.put("kaptcha.textproducer.font.color", "blue");
        // 验证码字体大小  
        properties.put("kaptcha.textproducer.font.size", "28");
        // 验证码所属字体样式  
        properties.put("kaptcha.textproducer.font.names", "Arial,Courier");
        // 干扰线颜色  
        properties.put("kaptcha.noise.color", "blue");
        // 验证码文本字符间距  
        properties.put("kaptcha.textproducer.char.space", "3");

        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
        for (HttpMessageConverter<?> httpMessageConverter : list) {
            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
                break;
            }
        }
        return restTemplate;
    }
}
